import 'package:flutter/foundation.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
import 'package:loxen/api/api.dart';
import 'package:loxen/api/http_server/user_info.dart';
import 'package:loxen/api/http_util.dart';
import 'package:loxen/mode/login_bean.dart';
import 'package:loxen/mode/code.dart';
import 'package:loxen/mode/mine/mine_information_mode.dart';
import 'package:loxen/mode/mine/user_info_edit.dart';
import 'package:loxen/mode/third_part_bean.dart';
import 'package:loxen/utils/config.dart';
import 'package:loxen/utils/save_util.dart';
import 'package:loxen/viewmode/base_view_model.dart';
import 'package:rxdart/rxdart.dart';

class CallBack {
  final void Function() onSuccess;
  final void Function(Exception error) onError;

  const CallBack(this.onSuccess, this.onError);
}

class LoginViewModel extends BaseViewModel with UserInfoMixin {
  LoginBean _loginBean;
  UserInfoEdit edit;
  MineInformation info;
  String userError;
  final JPush jPush = JPush();

  //未登录为true   登录为false
  bool isLogin() => _loginBean == null;

  LoginBean get loginBean => _loginBean;

  void initUser() async {
    String tonken = await SharedPreferencesUtil.getData(Constants.ACCESS_TOKEN);
    if (tonken != null && tonken != '') {
      bool flag =
          await Rx.zip2<UserInfoEdit, MineInformation, bool>(userData(), userInfo(), (edit, info) {
        if (edit != null && info != null) {
          this.edit = edit;
          this.info = info;
          return true;
        } else {
          return false;
        }
      }).first;
      if (flag) {
        _loginBean = LoginBean();
      }
    }
  }

  void jPushRidPost() {
    jPush.getRegistrationID().then((rid) {
      print('rid--$rid');
      ApiService.ridPost(rid).listen((event) {
        print(event);
      });
    });
  }

  void thirdPartLogin(String platform, String openid,
      {void Function() onSuccess, void Function(String error) onFail}) {
    ApiService.thirdPartLogin(platform, openid)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        _loginBean = event;
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      print(error);
    });
  }

  void getQQPermit(Map userData,
      {void Function(
        String platform,
        String openid,
        bool has_reg,
      )
          onSuccess,
      void Function(String error) onFail}) {
    ApiService.qqPermit(userData)
        .flatMap((value) => compute(decodeThirdPartBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        if (onSuccess != null)
          onSuccess.call(event.data.platform, event.data.openid, event.data.has_reg);
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      print(error);
      if (onFail != null) onFail.call(error.toString());
    });
  }

  void getWechatPermit(Map userData,
      {void Function(
        String platform,
        String openid,
        bool has_reg,
      )
          onSuccess,
      void Function(String error) onFail}) {
    ApiService.wechatPermit(userData)
        .flatMap((value) => compute(decodeThirdPartBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        if (onSuccess != null)
          onSuccess.call(event.data.platform, event.data.openid, event.data.has_reg);
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      print(error);
      if (onFail != null) onFail.call(error.toString());
    });
  }

  void getSinaPermit(Map userData,
      {void Function(
        String platform,
        String openid,
        bool has_reg,
      )
          onSuccess,
      void Function(String error) onFail}) {
    ApiService.sinaPermit(userData)
        .flatMap((value) => compute(decodeThirdPartBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        if (onSuccess != null)
          onSuccess.call(event.data.platform, event.data.openid, event.data.has_reg);
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      print(error);
      if (onFail != null) onFail.call(error.toString());
    });
  }

  void getApplePermit(Map userData,
      {void Function(
        String platform,
        String openid,
        bool has_reg,
      )
          onSuccess,
      void Function(String error) onFail}) {
    ApiService.applePermit(userData)
        .flatMap((value) => compute(decodeThirdPartBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        if (onSuccess != null)
          onSuccess.call(event.data.platform, event.data.openid, event.data.has_reg);
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      print(error);
      if (onFail != null) onFail.call(error.toString());
    });
  }

  void logout() {
    // 删除极光推送的rid
    ApiService.ridDelete().listen((event) {
      _loginBean = null;
      SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, '');
      SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, '');
      notifyListeners();
    });
  }

  void login(String mobile, String password,
      {void Function() onSuccess, void Function(String error) onFail}) {
    ApiService.login(mobile, password)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        _loginBean = event;
        SharedPreferencesUtil.putData(Constants.PHONE, mobile);
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            if (data["mobile"].toString() != null) {
              onFail.call(data["mobile"].toString());
            }
            if (data["password"].toString() != null) {
              onFail.call(data["password"].toString());
            }
          }
        }
      }
    });
  }

  void logincode(String mobile, String code,
      {void Function() onSuccess, void Function(String error) onFail}) {
    userError = '手机号错误';
    ApiService.logincode(mobile, code)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        _loginBean = event;
        SharedPreferencesUtil.putData(Constants.PHONE, mobile);
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            if (data['data']["mobile"].toString() != null) {
              onFail.call(data['data']["mobile"].toString());
            }
          }
        }
      }
    });
  }

  // 第三方注册
  void thirdPartRegister(String platform, String openid, String mobile, String code,
      {void Function() onSuccess, void Function(String error) onFail}) {
    ApiService.thirdPartRegister(platform, openid, mobile, code)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        _loginBean = event;
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            if (data["mobile"].toString() != null) {
              onFail.call(data["mobile"].toString());
            }
          }
        }
      }
    });
  }

  //zhuce
  void register(String nickname, String password, String mobile, String code, bool is_brand,
      {void Function() onSuccess, void Function(String error) onFail}) {
    notifyListeners();
    ApiService.register(nickname, password, mobile, code, is_brand)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        _loginBean = event;
        SharedPreferencesUtil.putData(Constants.PHONE, mobile);
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            if (data["mobile"] != null && data["mobile"].toString().trim() != "") {
              onFail.call(data["mobile"].toString());
            } else if (data["nickname"] != null && data["nickname"].toString().trim() != "") {
              onFail.call(data["nickname"].toString());
            }
          }
        }
      }
    });
  }

  void code(String mobile, String action,
      {void Function() onSuccess, void Function(String error) onFail}) {
    print(mobile);
    ApiService.code(mobile, action).listen((event) {
      if (event.statusCode == 201) {
        print(event.data);
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            onFail.call(data["mobile"].toString());
          }
        }
      }
    });
  }

  void password(String password, String newpassword,
      {void Function() onSuccess, void Function(String error) onFail}) {
    ApiService.password(password, newpassword)
        .flatMap((value) => compute(decodeLoginBean, value.data).asStream())
        .listen((event) {
      if (event.code == 2000) {
        SharedPreferencesUtil.putData(Constants.ACCESS_TOKEN, event.data.token);
        SharedPreferencesUtil.putData(Constants.REFRESH_TOKEN, event.data.rft);
        jPushRidPost();
        notifyListeners();
        if (onSuccess != null) onSuccess.call();
      } else {
        if (onFail != null) onFail.call('未知异常');
      }
    }, onError: (error) {
      if (onFail != null) {
        if (error is ServiceException) {
          var data = error.userMessage;
          if (data is Map) {
            if (data["password"].toString() != null) {
              onFail.call(data["password"].toString());
            }
          }
        }
      }
    });
  }

  static ThirdPartBean decodeThirdPartBean(dynamic json) {
    return ThirdPartBean.fromJson(json);
  }

  static LoginBean decodeLoginBean(dynamic json) {
    return LoginBean.fromJson(json);
  }

  static Roots decodeCode(dynamic json) {
    return Roots.fromJson(json);
  }
}
